import { _decorator, Component, Node, Sprite, Label, Vec3, v3, v2, SpriteFrame, Widget, UITransform, tween, Prefab, instantiate, ParticleSystem, ParticleSystem2D, AudioClip } from 'cc';
const { ccclass, property } = _decorator;

import { bdlMgr } from "../../../../Script/Manager/BundleManager_S";
import DragTetris_CardFunctions from "../Common/DragTetris_CardFunctions";
import { DragTetris_Consts } from "../Data/DragTetris_Consts";
import DragTetris_GameConfig from "../Data/DragTetris_GameConfig";
import { DragTetris_GameData } from "../Data/DragTetris_GameData";
import { DragTetris_BlockType, DragTetris_PosType } from "../Data/DragTetris_GameEnum";
import DragTetris_GameManager from "../Manager/DragTetris_GameManager";
import DragTetris_UIManager from "../Manager/DragTetris_UIManager";
import DragTetris_GamePanel from "../UI/DragTetris_GamePanel";
import DragTetris_Grid from "./DragTetris_Grid";
import { SSS_Consts } from 'db://assets/Script/Data/SSS_Consts';

@ccclass('DragTetrisBlock')
export default class DragTetris_Block extends Component {
    @property(Node)
    normal: Node | null = null;
    @property(Sprite)
    icon: Sprite | null = null;
    @property(Label)
    Label_point: Label | null = null;
    //    // blockType: DragTetris_BlockType = DragTetris_BlockType.NORMAL;
    //    // posType: PosType = PosType.CONCTROL;
    x: number = 0;
    y: number = 0;
    length: number = 1;
    color: number = 0;
    point: number;
    is装满 = false;
    isDead: boolean = false;
    startPos;
    grid: DragTetris_Grid = null;
    canMove: boolean = true;
    newPosition: Vec3;
    initPosition: Vec3;
    create_x;
    //    // 只序列化需要的属性
    toJSON() {
        return {
            // blockType: this.blockType,
            x: this.x,
            y: this.y,
            color: this.color,
            point: this.point,
            // // _class: 'MyClass' // 添加类标识以便反序列化
        };
    }
    //    // 初始化
    init(_posType: DragTetris_PosType, _x: number, _y: number, _point: number, _color: number) {
        // this.blockType = _blockType;
        // this.posType = _posType;
        this.x = _x;
        this.create_x = this.x;
        this.y = _y;
        this.point = _point;
        this.color = _color;


        this.node.active = true;

        this.node.position = v3(0, 0, 0);

        this.startPos = this.node.position;

        this.node.getComponent(UITransform).width = DragTetris_GameConfig.size;
        this.node.getComponent(UITransform).height = DragTetris_GameConfig.size;


        this.RefreshSprite();

        // this.AddListener();
    }
    async RefreshSprite() {
        // TODO?
        // console.log(`this.color`, this.color);

        const sp = await bdlMgr.getRes<SpriteFrame>('DragTetris_Sprite', `block/block_00${this.color + 1}_1/spriteFrame`, SpriteFrame);
        // console.log(`sp`, sp);
        this.icon.spriteFrame = sp;
        // TODO?

        this.icon.node.getComponent(Widget).enabled = false;
        this.icon.node.getComponent(UITransform).width = this.node.getComponent(UITransform).width - 0;
        this.icon.node.getComponent(UITransform).height = this.node.getComponent(UITransform).height - 0;

        // this.Label_point.string = `${this.point}`;
    }
    GetNodeWorldPostation(_node: Node): Vec3 {
        let pos: Vec3 = v3();
        if (_node.parent == null) {
            pos = v3(_node.getPosition());
        } else {
            // pos = v3(_node.parent.convertToWorldSpaceAR(_node.getPosition()));
            pos = _node.getWorldPosition();
        }
        return pos;
    }
    AddListener() {
        // this.node.on(Node.EventType.TOUCH_START, this.TOUCH_START, this);
        // this.node.on(Node.EventType.TOUCH_MOVE, this.TOUCH_MOVE, this);
        // this.node.on(Node.EventType.TOUCH_END, this.TOUCH_END, this);
        // this.node.on(Node.EventType.TOUCH_CANCEL, this.TOUCH_END, this);
    }
    async TOUCH_START(t) {
        if (!this.canMove) {
            return;
        }

        DragTetris_GameData.IsMouseDown = true;

        this.node.scale = v3(1, 1, 1);
        const location = t.getLocation();
        this.initPosition = this.node.position;
        DragTetris_GameData.StartPos = location;

        DragTetris_CardFunctions.SetAllGridCanPlaceForce(true);
        DragTetris_CardFunctions.SetAllGridCanPlaceByBlock(this);
        DragTetris_CardFunctions.RefreshAllGridCanPlace();
    }
    TOUCH_MOVE(t) {
        DragTetris_CardFunctions.AllGridSelect(false);

        if (!this.canMove) {
            return;
        }


        if (DragTetris_GameData.IsMouseDown === true) {
            const location = t.getLocation();

            DragTetris_GameData.CurrentPos = location;

            // let diff = v3(DragTetris_GameData.CurrentPos.sub(DragTetris_GameData.StartPos));
            let current = new Vec3(DragTetris_GameData.CurrentPos.x, DragTetris_GameData.CurrentPos.y, 0);
            let start = new Vec3(DragTetris_GameData.StartPos.x, DragTetris_GameData.StartPos.y, 0);
            let diff = Vec3.subtract(new Vec3(), current, start);


            let pos = v3(this.initPosition.x + diff.x, this.initPosition.y + diff.y, this.initPosition.z);
            this.node.position = pos;

            // let p1 = this.node.convertToWorldSpaceAR(v2(0, 0));
            // let p2 = DragTetris_UIManager.Instance.Root_grid.convertToNodeSpaceAR(p1);
            let p1 = this.node.getComponent(UITransform)!.convertToWorldSpaceAR(new Vec3(0, 0, 0));
            let p2 = DragTetris_UIManager.Instance.Root_grid.getComponent(UITransform)!.convertToNodeSpaceAR(p1);



            const x_new = this.GetXByX(p2.x);
            const y_new = this.GetXByY(p2.y);

            let grid: DragTetris_Grid = DragTetris_CardFunctions.GetGrid(x_new, y_new)
            if (grid && grid.block === null) {
                grid.Select(true);
            }

            DragTetris_CardFunctions.SetAllGridCanPlaceForce(true);
            DragTetris_CardFunctions.SetAllGridCanPlaceByBlock(this);
            DragTetris_CardFunctions.RefreshAllGridCanPlace();
        }
    }
    TOUCH_END() {
        DragTetris_CardFunctions.AllGridSelect(false);

        if (!this.canMove) {
            return;
        }

        DragTetris_GameData.IsMouseDown = false;

        let fun_list = [];
        let isTag: boolean = true;
        const block: DragTetris_Block = this;

        // let p1 = block.node.convertToWorldSpaceAR(v2(0, 0));
        // let p2 = DragTetris_UIManager.Instance.Root_grid.convertToNodeSpaceAR(p1);
        let p1 = block.node.getComponent(UITransform)!.convertToWorldSpaceAR(new Vec3(0, 0, 0));
        let p2 = DragTetris_UIManager.Instance.Root_grid.getComponent(UITransform)!.convertToNodeSpaceAR(p1);


        const x_new = block.GetXByX(p2.x);
        const y_new = block.GetXByY(p2.y);

        let grid: DragTetris_Grid = DragTetris_CardFunctions.GetGrid(x_new, y_new)
        if (grid && grid.block === null && grid.canPlace === true) {
            let fun = () => {
                this.x = x_new;
                this.y = y_new;
                grid.block = block;
                block.grid = grid;
                block.node.parent = block.grid.node;
                block.node.position = v3(0, 0, 0);
            }
            fun_list.push(fun);
        }
        else {
            isTag = false;
        }

        if (isTag) {
            for (let index = 0; index < fun_list.length; index++) {
                const fun = fun_list[index];
                fun();
            }
            this.canMove = false;

            let blockType = DragTetris_BlockType.NORMAL;
            // let posType = PosType.CONCTROL;
            let x = this.create_x;
            let y = -1;
            let point = DragTetris_CardFunctions.GetRandomPoint();
            let color = DragTetris_CardFunctions.GetRandomColor();
            // DragTetris_CardFunctions.CreateBlock(blockType, posType, x, y, point, color);

            DragTetris_GameManager.Main();
        }
        else {
            this.node.position = this.startPos;
            // this.node.scale = this.minScale;
        }

        DragTetris_CardFunctions.SetAllGridCanPlaceForce(true);
    }
    GetXByX(x_pos: number) {
        let x = (x_pos - (-DragTetris_GameConfig.W / 2 + this.node.getComponent(UITransform).width / 2)) / DragTetris_GameConfig.size + 0.5;
        let x_int = Math.floor(x);
        return x_int;
    }
    GetXByY(y_pos: number) {
        let y = (y_pos - (-DragTetris_GameConfig.H / 2 + this.node.getComponent(UITransform).height / 2)) / DragTetris_GameConfig.size + 0.5;
        let x_int = Math.floor(y);
        return x_int;
    }
    DestroyAnimation(callback: Function = null) {
        if (this.isDead) {
            return;
        }


        this.isDead = true;

        const score = DragTetris_CardFunctions.GetScore();
        // GameData.Score += score;
        DragTetris_GameData.SetScore(DragTetris_GameData.GetScore() + score);

        DragTetris_GameData.UpdateScore();
        // GameFunctions.LevelUp();
        DragTetris_GamePanel.Instance.Refresh();


        // let p2 = DragTetris_UIManager.Instance.Root_effect.convertToNodeSpaceAR(this.node.convertToWorldSpaceAR(Vec2.ZERO));
        let worldPos = this.node.getComponent(UITransform)!.convertToWorldSpaceAR(new Vec3(0, 0, 0));
        let p2 = DragTetris_UIManager.Instance.Root_effect.getComponent(UITransform)!.convertToNodeSpaceAR(worldPos);

        let color = this.color;

        let duration: number = 0.1;
        tween(this.node)
            // .to(0.14, { scale: 0.5, opacity: 255 }, { easing: "" })
            // .to(0.14, { scale: 1.2, opacity: 255 }, { easing: "" })
            .to(0.14, { scale: v3(0.5, 0.5, 0.5) })
            .to(0.14, { scale: v3(1.2, 1.2, 1.2) })

            // .to(0.05, { scale: 0.5, opacity: 100 })
            // .to(duration, { scale: 1, opacity: 255 }, { easing: "" })

            .call(async () => {
                const prefab = await bdlMgr.getRes<Prefab>(DragTetris_Consts.BundleName.PREFAB, `ParticleSystem_explode`, Prefab);

                let ParticleSystem_explode = instantiate(prefab);
                ParticleSystem_explode.active = true;

                const sp = await bdlMgr.getRes<SpriteFrame>(DragTetris_Consts.BundleName.SPRITE, `block/block_00${this.color + 1}_1/spriteFrame`, SpriteFrame);

                const ps = ParticleSystem_explode.getComponent(ParticleSystem2D);
                ps.spriteFrame = sp;

                ParticleSystem_explode.parent = DragTetris_UIManager.Instance.Root_effect;


                ParticleSystem_explode.setPosition(p2);


                // // // let root = `audio/Button1`
                // let root = `audio/水音效2`
                // // bdlMgr.getRes<AudioClip>(SSS_Consts.BundleName.AUDIO, `audio/符文碎裂`, AudioClip).then(res => {
                // bdlMgr.getRes<AudioClip>(SSS_Consts.BundleName.AUDIO, root, AudioClip).then(res => {
                //     if (res) {
                //         AudioManager.Instance.playSFX(res, false);
                //         // audioEngine.setVolume(audioId, 0.6);
                //     }
                // });


                // this.node.destroy();
                if (callback) {
                    callback();
                }
            })

            // .to(0.05, { scale: 0.1, opacity: 10 })
            .to(0.05, { scale: v3(0.1, 0.1, 0.1) })
            .call(() => {
                this.node.destroy();
            })

            .start();
    }
    Destroy() {
        this.node.destroy();
    }
}